package com.halden.mycache.support.aop;

import com.halden.mycache.support.listener.ISlowLogListener;
import com.halden.mycache.support.listener.SlowLogContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: halden
 * @Data:2023/2/11 18:32
 * @Description: 日志切面类
 */
@Component
@Aspect
public class SlowLogAspect {

    /**
     * 静态的慢日志监听器链条，便于工厂初始化时进行注入
     * @since 0.0.4
     */
    private static List<ISlowLogListener> slowLogListenerList = new ArrayList<>();

    /**
     * 慢日志的上下文对象
     */
    private SlowLogContext slowLogContext;

    /**
     * 是否开启慢日志，默认关闭
     */
    private static boolean flag = false;

    /**
     * 增加慢日志监听器的方法
     * @param slowLogListener
     * @since 0.0.4
     */
    public static void addSlowLogListener(ISlowLogListener slowLogListener){
        slowLogListenerList.add(slowLogListener);
    }

    /**
     * 开启慢日志的方法
     * @since 0.0.4
     */
    public static void openSlowLog(){
        flag = true;
    }

    /**
     * 确定切点
     */
    @Pointcut("@annotation(com.halden.mycache.support.aop.CacheInterceptor)")
    public void action() {
    }

    @Before("action()")
    public void before(JoinPoint joinPoint) {
        if (flag == false){
            return;
        }
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        Object[] args = joinPoint.getArgs();
        this.slowLogContext = new SlowLogContext()
                .method(method)
                .params(args);
        slowLogContext.setStart(new Date());
    }

    @AfterReturning("action()")
    public void after(JoinPoint joinPoint) {
        if (flag == false){
            return;
        }
        slowLogContext.setEnd(new Date());
        for (ISlowLogListener slowLogListener : slowLogListenerList){
            slowLogListener.listen(this.slowLogContext);
        }
    }

}
